home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / app / interface.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-01-15  |  38.2 KB  |  1,311 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <string.h>
  22.  
  23. #include <gtk/gtk.h>
  24.  
  25. #include "apptypes.h"
  26.  
  27. #include "appenv.h"
  28. #include "app_procs.h"
  29. #include "color_area.h"
  30. #include "commands.h"
  31. #include "devices.h"
  32. #include "dialog_handler.h"
  33. #include "disp_callbacks.h"
  34. #include "fileops.h"
  35. #include "gdisplay.h"
  36. #include "gdisplay_ops.h"
  37. #include "gimage.h"
  38. #include "gimpdnd.h"
  39. #include "gimphelp.h"
  40. #include "gimprc.h"
  41. #include "gimpui.h"
  42. #include "gtkhwrapbox.h"
  43. #include "gtkvwrapbox.h"
  44. #include "indicator_area.h"
  45. #include "interface.h"
  46. #include "menus.h"
  47. #include "nav_window.h"
  48. #include "qmask.h"
  49. #include "session.h"
  50. #include "tools.h"
  51.  
  52. #include "pixmaps.h"
  53. #include "pixmaps/qmasksel.xpm"
  54. #include "pixmaps/qmasknosel.xpm"
  55. #include "pixmaps/navbutton.xpm"
  56.  
  57. #include "libgimp/gimpintl.h"
  58.  
  59.  
  60. /*  local functions  */
  61. static void  tools_select_update   (GtkWidget      *widget,
  62.                     gpointer        data);
  63. static gint  tools_button_press    (GtkWidget      *widget,
  64.                     GdkEventButton *bevent,
  65.                     gpointer        data);
  66. static void  gdisplay_destroy      (GtkWidget      *widget,
  67.                     GDisplay       *display);
  68.  
  69. static gint  gdisplay_delete       (GtkWidget      *widget,
  70.                     GdkEvent       *event,
  71.                     GDisplay       *display);
  72.  
  73. static void  toolbox_destroy       (void);
  74. static gint  toolbox_delete        (GtkWidget      *widget,
  75.                     GdkEvent       *event,
  76.                     gpointer        data);
  77. static gint  toolbox_check_device  (GtkWidget      *widget,
  78.                     GdkEvent       *event,
  79.                     gpointer        data);
  80.  
  81. static GdkPixmap *create_pixmap    (GdkWindow      *parent,
  82.                     GdkBitmap     **mask,
  83.                     gchar         **data,
  84.                     gint            width,
  85.                     gint            height);
  86.  
  87. static void     toolbox_style_set_callback (GtkWidget        *window,
  88.                         GtkStyle         *previous_style,
  89.                         gpointer          data);
  90. static void     toolbox_set_drag_dest      (GtkWidget        *widget);
  91. static gboolean toolbox_drag_drop          (GtkWidget        *widget,
  92.                         GdkDragContext   *context,
  93.                         gint              x,
  94.                         gint              y,
  95.                         guint             time);
  96. static ToolType toolbox_drag_tool          (GtkWidget        *widget,
  97.                         gpointer          data);
  98. static void     toolbox_drop_tool          (GtkWidget        *widget,
  99.                         ToolType          tool,
  100.                         gpointer          data);
  101.  
  102. static gint pixmap_colors[8][3] =
  103. {
  104.   { 0x00, 0x00, 0x00 }, /* a -   0 */
  105.   { 0x24, 0x24, 0x24 }, /* b -  36 */
  106.   { 0x49, 0x49, 0x49 }, /* c -  73 */
  107.   { 0x6D, 0x6D, 0x6D }, /* d - 109 */
  108.   { 0x92, 0x92, 0x92 }, /* e - 146 */
  109.   { 0xB6, 0xB6, 0xB6 }, /* f - 182 */
  110.   { 0xDB, 0xDB, 0xDB }, /* g - 219 */
  111.   { 0xFF, 0xFF, 0xFF }, /* h - 255 */
  112. };
  113.  
  114. #define COLUMNS 3
  115. #define ROWS    8
  116. #define MARGIN  2
  117.  
  118. /*  local variables  */
  119. static GdkColor    colors[11];
  120. static GtkWidget * toolbox_shell = NULL;
  121.  
  122. static GtkTargetEntry toolbox_target_table[] =
  123. {
  124.   GIMP_TARGET_URI_LIST,
  125.   GIMP_TARGET_TEXT_PLAIN,
  126.   GIMP_TARGET_NETSCAPE_URL,
  127.   GIMP_TARGET_LAYER,
  128.   GIMP_TARGET_CHANNEL,
  129.   GIMP_TARGET_LAYER_MASK,
  130.   GIMP_TARGET_TOOL
  131. };
  132. static guint toolbox_n_targets = (sizeof (toolbox_target_table) /
  133.                   sizeof (toolbox_target_table[0]));
  134.  
  135. static GtkTargetEntry tool_target_table[] =
  136. {
  137.   GIMP_TARGET_TOOL
  138. };
  139. static guint tool_n_targets = (sizeof (tool_target_table) /
  140.                    sizeof (tool_target_table[0]));
  141.  
  142. static GtkTargetEntry display_target_table[] =
  143. {
  144.   GIMP_TARGET_LAYER,
  145.   GIMP_TARGET_CHANNEL,
  146.   GIMP_TARGET_LAYER_MASK,
  147.   GIMP_TARGET_COLOR,
  148.   GIMP_TARGET_PATTERN
  149. };
  150. static guint display_n_targets = (sizeof (display_target_table) /
  151.                   sizeof (display_target_table[0]));
  152.  
  153. static void
  154. tools_select_update (GtkWidget *widget,
  155.              gpointer   data)
  156. {
  157.   ToolType tool_type;
  158.  
  159.   tool_type = (ToolType) data;
  160.  
  161.   if ((tool_type != -1) && GTK_TOGGLE_BUTTON (widget)->active)
  162.     gimp_context_set_tool (gimp_context_get_user (), tool_type);
  163. }
  164.  
  165. static gint
  166. tools_button_press (GtkWidget      *widget,
  167.             GdkEventButton *event,
  168.             gpointer        data)
  169. {
  170.   GDisplay * gdisp;
  171.   gdisp = data;
  172.  
  173.   if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1))
  174.     tool_options_dialog_show ();
  175.  
  176.   return FALSE;
  177. }
  178.  
  179. static gint
  180. toolbox_delete (GtkWidget *widget,
  181.         GdkEvent  *event,
  182.         gpointer   data)
  183. {
  184.   app_exit (FALSE);
  185.  
  186.   return TRUE;
  187. }
  188.  
  189. static void
  190. toolbox_destroy (void)
  191. {
  192.   app_exit_finish ();
  193. }
  194.  
  195. static gint
  196. toolbox_check_device (GtkWidget *widget,
  197.               GdkEvent  *event,
  198.               gpointer   data)
  199. {
  200.   devices_check_change (event);
  201.  
  202.   return FALSE;
  203. }
  204.  
  205. static void
  206. gdisplay_destroy (GtkWidget *widget,
  207.           GDisplay  *gdisp)
  208. {
  209.   gdisplay_remove_and_delete (gdisp);
  210. }
  211.  
  212. static gint
  213. gdisplay_delete (GtkWidget *widget,
  214.          GdkEvent  *event,
  215.          GDisplay  *gdisp)
  216. {
  217.   gdisplay_close_window (gdisp, FALSE);
  218.  
  219.   return TRUE;
  220. }
  221.  
  222. static void
  223. allocate_colors (GtkWidget *parent)
  224. {
  225.   GdkColormap *colormap;
  226.   gint i;
  227.  
  228.   gtk_widget_realize (parent);
  229.   colormap = gdk_window_get_colormap (parent->window);
  230.  
  231.   for (i = 0; i < 8; i++)
  232.     {
  233.       colors[i].red = pixmap_colors[i][0] << 8;
  234.       colors[i].green = pixmap_colors[i][1] << 8;
  235.       colors[i].blue = pixmap_colors[i][2] << 8;
  236.  
  237.       gdk_color_alloc (colormap, &colors[i]);
  238.     }
  239.  
  240.   colors[8] = parent->style->bg[GTK_STATE_NORMAL];
  241.   gdk_color_alloc (colormap, &colors[8]);
  242.  
  243.   colors[9] = parent->style->bg[GTK_STATE_ACTIVE];
  244.   gdk_color_alloc (colormap, &colors[9]);
  245.  
  246.   colors[10] = parent->style->bg[GTK_STATE_PRELIGHT];
  247.   gdk_color_alloc (colormap, &colors[10]);
  248. }
  249.  
  250. static void
  251. create_indicator_area (GtkWidget *parent)
  252. {
  253.   GtkWidget *frame;
  254.   GtkWidget *alignment;
  255.   GtkWidget *ind_area;
  256.  
  257.   if (! GTK_WIDGET_REALIZED (parent))
  258.     gtk_widget_realize (parent);
  259.  
  260.   frame = gtk_frame_new (NULL);
  261.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  262.   gtk_wrap_box_pack (GTK_WRAP_BOX (parent), frame, TRUE, TRUE, TRUE, TRUE);
  263.  
  264.   alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  265.   gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
  266.   gtk_container_add (GTK_CONTAINER (frame), alignment);
  267.  
  268.   gimp_help_set_help_data (alignment, NULL, "#indicator_area");
  269.  
  270.   ind_area = indicator_area_create ();
  271.   gtk_container_add (GTK_CONTAINER (alignment), ind_area);
  272.  
  273.   gtk_widget_show (ind_area);
  274.   gtk_widget_show (alignment);
  275.   gtk_widget_show (frame);
  276. }
  277.  
  278. static void
  279. create_color_area (GtkWidget *parent)
  280. {
  281.   GtkWidget *frame;
  282.   GtkWidget *alignment;
  283.   GtkWidget *col_area;
  284.   GdkPixmap *default_pixmap;
  285.   GdkBitmap *default_mask;
  286.   GdkPixmap *swap_pixmap;
  287.   GdkBitmap *swap_mask;
  288.  
  289.   if (! GTK_WIDGET_REALIZED (parent))
  290.     gtk_widget_realize (parent);
  291.  
  292.   default_pixmap = create_pixmap (parent->window, &default_mask, default_bits,
  293.                   default_width, default_height);
  294.   swap_pixmap    = create_pixmap (parent->window, &swap_mask, swap_bits,
  295.                   swap_width, swap_height);
  296.  
  297.   frame = gtk_frame_new (NULL);
  298.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  299.   gtk_wrap_box_pack (GTK_WRAP_BOX (parent), frame, TRUE, TRUE, TRUE, TRUE);
  300.   gtk_wrap_box_set_child_forced_break (GTK_WRAP_BOX (parent), frame, TRUE);
  301.  
  302.   alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  303.   gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
  304.   gtk_container_add (GTK_CONTAINER (frame), alignment);
  305.  
  306.   gimp_help_set_help_data (alignment, NULL, "#color_area");
  307.  
  308.   col_area = color_area_create (54, 42,
  309.                 default_pixmap, default_mask,
  310.                 swap_pixmap, swap_mask);
  311.   gtk_container_add (GTK_CONTAINER (alignment), col_area);
  312.   gimp_help_set_help_data
  313.     (col_area,
  314.      _("Foreground & background colors.  The black "
  315.        "and white squares reset colors.  The arrows swap colors. Double "
  316.        "click to select a color from a colorrequester."), NULL);
  317.  
  318.   gtk_widget_show (col_area);
  319.   gtk_widget_show (alignment);
  320.   gtk_widget_show (frame);
  321. }
  322.  
  323. /* creates all icons */
  324. static void
  325. create_tool_pixmaps (GtkWidget *parent)
  326. {
  327.   gint i;
  328.  
  329.   g_return_if_fail (parent != NULL);
  330.  
  331.   for (i = 0; i < num_tools; i++)
  332.     {
  333.       if (tool_info[i].icon_data)
  334.     tool_info[i].icon_pixmap = create_pixmap (parent->window, 
  335.                           &tool_info[i].icon_mask,
  336.                           tool_info[i].icon_data,
  337.                           22, 22);
  338.       else
  339.     tool_info[i].icon_pixmap = create_pixmap (parent->window,  
  340.                           &tool_info[i].icon_mask,
  341.                           dialog_bits,
  342.                           22, 22);
  343.     }
  344. }
  345.  
  346. static void
  347. create_tools (GtkWidget *parent)
  348. {
  349.   GtkWidget *wbox;
  350.   GtkWidget *button;
  351.   GtkWidget *alignment;
  352.   GtkWidget *pixmap;
  353.   GSList *group;
  354.   gint    i, j;
  355.  
  356.   wbox = parent;
  357.  
  358.   if (! GTK_WIDGET_REALIZED (gtk_widget_get_toplevel (wbox)))
  359.     gtk_widget_realize (gtk_widget_get_toplevel (wbox));
  360.  
  361.   create_tool_pixmaps (wbox);
  362.  
  363.   group = NULL;
  364.  
  365.   i = 0;
  366.   for (j = 0; j < num_tools; j++)
  367.     {
  368.       if (j <= LAST_TOOLBOX_TOOL &&
  369.       j != SCALE && j!= SHEAR && j != PERSPECTIVE)
  370.     {
  371.       tool_info[j].tool_widget = button = gtk_radio_button_new (group);
  372.       gtk_container_set_border_width (GTK_CONTAINER (button), 0);
  373.       group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  374.  
  375.       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
  376.  
  377.       gtk_wrap_box_pack (GTK_WRAP_BOX (wbox), button,
  378.                  FALSE, FALSE, FALSE, FALSE);
  379.  
  380.       alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  381.       gtk_container_set_border_width (GTK_CONTAINER (alignment), 0);
  382.       gtk_container_add (GTK_CONTAINER (button), alignment);
  383.  
  384.       pixmap = gtk_pixmap_new (tool_get_pixmap ((ToolType)j), 
  385.                    tool_get_mask ((ToolType)j));
  386.       gtk_container_add (GTK_CONTAINER (alignment), pixmap);
  387.  
  388.       gtk_signal_connect (GTK_OBJECT (button), "toggled",
  389.                   GTK_SIGNAL_FUNC (tools_select_update),
  390.                   (gpointer) tool_info[j].tool_id);
  391.  
  392.       gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
  393.                   GTK_SIGNAL_FUNC (tools_button_press),
  394.                   (gpointer) tool_info[j].tool_id);
  395.  
  396.       /*  dnd stuff  */
  397.       gtk_drag_source_set (tool_info[j].tool_widget,
  398.                    GDK_BUTTON2_MASK,
  399.                    tool_target_table, tool_n_targets,
  400.                    GDK_ACTION_COPY);
  401.       gimp_dnd_tool_source_set (tool_info[j].tool_widget,
  402.                     toolbox_drag_tool,
  403.                     GINT_TO_POINTER (j));
  404.  
  405.       gimp_help_set_help_data (button,
  406.                    gettext(tool_info[j].tool_desc),
  407.                    tool_info[j].private_tip);
  408.  
  409.       gtk_widget_show (pixmap);
  410.       gtk_widget_show (alignment);
  411.       gtk_widget_show (button);
  412.       i++;
  413.     }
  414.       else
  415.     {
  416.       tool_info[j].tool_widget = button = gtk_radio_button_new (group);
  417.       group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  418.  
  419.       gtk_signal_connect (GTK_OBJECT (button), "clicked",
  420.                   GTK_SIGNAL_FUNC (tools_select_update),
  421.                   (gpointer) tool_info[j].tool_id);
  422.     }
  423.     }
  424.  
  425.   gtk_widget_show (wbox);
  426. }
  427.  
  428. static GdkPixmap *
  429. create_pixmap (GdkWindow  *parent,
  430.            GdkBitmap **mask,
  431.            gchar     **data,
  432.            gint        width,
  433.            gint        height)
  434. {
  435.   GdkPixmap   *pixmap;
  436.   GdkImage    *image;
  437.   GdkGC       *gc;
  438.   GdkVisual   *visual;
  439.   GdkColormap *cmap;
  440.   gint     r, s, t, cnt;
  441.   guchar  *mem;
  442.   guchar   value;
  443.   guint32  pixel;
  444.  
  445.   visual = gdk_window_get_visual (parent);
  446.   cmap = gdk_window_get_colormap (parent);
  447.   image = gdk_image_new (GDK_IMAGE_NORMAL, visual, width, height);
  448.   pixmap = gdk_pixmap_new (parent, width, height, -1);
  449.   gc = NULL;
  450.  
  451.   if (mask)
  452.     {
  453.       GdkColor tmp_color;
  454.  
  455.       *mask = gdk_pixmap_new (parent, width, height, 1);
  456.       gc = gdk_gc_new (*mask);
  457.       gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
  458.  
  459.       tmp_color.pixel = 1;
  460.       gdk_gc_set_foreground (gc, &tmp_color);
  461.     }
  462.  
  463.   for (r = 0; r < height; r++)
  464.     {
  465.       mem = image->mem;
  466.       mem += image->bpl * r;
  467.  
  468.       for (s = 0, cnt = 0; s < width; s++)
  469.     {
  470.       value = data[r][s];
  471.  
  472.       if (value == '.')
  473.         {
  474.           pixel = colors[8].pixel;
  475.  
  476.           if (mask)
  477.         {
  478.           if (cnt < s)
  479.             gdk_draw_line (*mask, gc, cnt, r, s - 1, r);
  480.           cnt = s + 1;
  481.         }
  482.         }
  483.       else
  484.         {
  485.           pixel = colors[value - 'a'].pixel;
  486.         }
  487.  
  488.       if (image->byte_order == GDK_LSB_FIRST)
  489.         {
  490.           for (t = 0; t < image->bpp; t++)
  491.         *mem++ = (guchar) ((pixel >> (t * 8)) & 0xFF);
  492.         }
  493.       else
  494.         {
  495.           for (t = 0; t < image->bpp; t++)
  496.         *mem++ = (guchar) ((pixel >> ((image->bpp - t - 1) * 8)) & 0xFF);
  497.         }
  498.     }
  499.  
  500.       if (mask && (cnt < s))
  501.     gdk_draw_line (*mask, gc, cnt, r, s - 1, r);
  502.     }
  503.  
  504.   if (mask)
  505.     gdk_gc_destroy (gc);
  506.  
  507.   gc = gdk_gc_new (parent);
  508.   gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, width, height);
  509.   gdk_gc_destroy (gc);
  510.   gdk_image_destroy (image);
  511.  
  512.   return pixmap;
  513. }
  514.  
  515. void
  516. create_toolbox (void)
  517. {
  518.   GtkWidget *window;
  519.   GtkWidget *main_vbox;
  520.   GtkWidget *wbox;
  521.   GtkWidget *menubar;
  522.   GList     *list;
  523.   GtkAccelGroup *table;
  524.  
  525.  
  526.   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  527.  
  528.   /* Register dialog */
  529.   dialog_register_toolbox (window);
  530.  
  531.   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
  532.               GTK_SIGNAL_FUNC (toolbox_delete),
  533.               NULL);
  534.  
  535.   gtk_signal_connect (GTK_OBJECT (window), "destroy",
  536.               GTK_SIGNAL_FUNC (toolbox_destroy),
  537.               NULL);
  538.  
  539.   /* We need to know when the current device changes, so we can update
  540.    * the correct tool - to do this we connect to motion events.
  541.    * We can't just use EXTENSION_EVENTS_CURSOR though, since that
  542.    * would get us extension events for the mouse pointer, and our
  543.    * device would change to that and not change back. So we check
  544.    * manually that all devices have a cursor, before establishing the check.
  545.    */
  546.   for (list = gdk_input_list_devices (); list; list = g_list_next (list))
  547.     {
  548.       if (!((GdkDeviceInfo *) (list->data))->has_cursor)
  549.     break;
  550.     }
  551.  
  552.   if (!list)  /* all devices have cursor */
  553.     {
  554.       gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
  555.               GTK_SIGNAL_FUNC (toolbox_check_device),
  556.               NULL);
  557.  
  558.       gtk_widget_set_events (window, GDK_POINTER_MOTION_MASK);
  559.       gtk_widget_set_extension_events (window, GDK_EXTENSION_EVENTS_CURSOR);
  560.     }
  561.   
  562.   /* set up the window geometry after the events have been set, 
  563.      since we need to realize the widget */
  564.   gtk_window_set_wmclass (GTK_WINDOW (window), "toolbox", "Gimp");
  565.   gtk_window_set_title (GTK_WINDOW (window), _("The GIMP"));
  566.   gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
  567.  
  568.   gtk_signal_connect (GTK_OBJECT (window), "style_set",
  569.               GTK_SIGNAL_FUNC (toolbox_style_set_callback),
  570.               NULL);
  571.  
  572.   session_set_window_geometry (window, &toolbox_session_info, TRUE);
  573.  
  574.   main_vbox = gtk_vbox_new (FALSE, 1);
  575.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
  576.   gtk_container_add (GTK_CONTAINER (window), main_vbox);
  577.   gtk_widget_show (main_vbox);
  578.  
  579.   /*  allocate the colors for creating pixmaps  */
  580.   allocate_colors (main_vbox);
  581.  
  582.   /*  tooltips  */
  583.   gimp_help_init ();
  584.   if (!show_tool_tips)
  585.     gimp_help_disable_tooltips ();
  586.  
  587.   /*  Build the menu bar with menus  */
  588.   menus_get_toolbox_menubar (&menubar, &table);
  589.   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
  590.   gtk_widget_show (menubar);
  591.  
  592.   /*  Install the accelerator table in the main window  */
  593.   gtk_window_add_accel_group (GTK_WINDOW (window), table);
  594.  
  595.   /*  Connect the "F1" help key  */
  596.   gimp_help_connect_help_accel (window,
  597.                 gimp_standard_help_func,
  598.                 "toolbox/toolbox.html");
  599.  
  600.   wbox = gtk_hwrap_box_new (FALSE);
  601.   gtk_wrap_box_set_justify (GTK_WRAP_BOX (wbox), GTK_JUSTIFY_TOP);
  602.   gtk_wrap_box_set_line_justify (GTK_WRAP_BOX (wbox), GTK_JUSTIFY_LEFT);
  603.   /*  magic number to set a default 5x5 layout  */
  604.   gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (wbox), 5.0 / 5.9);
  605.   gtk_container_set_border_width (GTK_CONTAINER (wbox), 0);
  606.   gtk_box_pack_start (GTK_BOX (main_vbox), wbox, TRUE, TRUE, 0);
  607.   gtk_widget_show (wbox);
  608.  
  609.   create_tools (wbox);
  610.  
  611.   create_color_area (wbox);
  612.   if (show_indicators)
  613.     create_indicator_area (wbox);
  614.  
  615.   gtk_widget_show (window);
  616.   toolbox_set_drag_dest (window);
  617.  
  618.   toolbox_shell = window;
  619. }
  620.  
  621. void
  622. toolbox_free (void)
  623. {
  624.   gint i;
  625.  
  626.   session_get_window_info (toolbox_shell, &toolbox_session_info);
  627.  
  628.   gtk_widget_destroy (toolbox_shell);
  629.   for (i = 0; i < num_tools; i++)
  630.     {
  631.       if (tool_info[i].icon_pixmap)
  632.     gdk_pixmap_unref (tool_info[i].icon_pixmap);
  633.       
  634.       if (!tool_info[i].icon_data)
  635.     gtk_object_sink (GTK_OBJECT (tool_info[i].tool_widget));
  636.     }
  637.   gimp_help_free ();
  638. }
  639.  
  640. void
  641. toolbox_raise_callback (GtkWidget *widget,
  642.             gpointer   data)
  643. {
  644.   gdk_window_raise (toolbox_shell->window);
  645. }
  646.  
  647. static void
  648. toolbox_style_set_callback (GtkWidget *window,
  649.                 GtkStyle  *previous_style,
  650.                 gpointer   data)
  651. {
  652.   GdkGeometry  geometry;
  653.   GtkStyle    *style;
  654.   gint         xthickness;
  655.   gint         ythickness;
  656.  
  657.   style = gtk_widget_get_style (window);
  658.   xthickness = ((GtkStyleClass *) style->klass)->xthickness;
  659.   ythickness = ((GtkStyleClass *) style->klass)->ythickness;
  660.   
  661.   geometry.min_width  =  2 + 24 + 2 * xthickness;
  662.   geometry.min_height = 80 + 24 + 2 * ythickness;
  663.   geometry.width_inc  =      24 + 2 * xthickness;
  664.   geometry.height_inc =      24 + 2 * ythickness;
  665.  
  666.   gtk_window_set_geometry_hints (GTK_WINDOW (window), 
  667.                  NULL,
  668.                  &geometry, 
  669.                  GDK_HINT_MIN_SIZE | GDK_HINT_RESIZE_INC);
  670. }
  671.  
  672. void
  673. create_display_shell (GDisplay *gdisp,
  674.               gint      width,
  675.               gint      height,
  676.               gchar    *title,
  677.               gint      type)
  678. {
  679.   static GtkWidget     *image_popup_menu  = NULL;
  680.   static GtkAccelGroup *image_accel_group = NULL;
  681.  
  682.   static GdkPixmap *qmasksel_pixmap   = NULL;
  683.   static GdkBitmap *qmasksel_mask     = NULL;
  684.   static GdkPixmap *qmasknosel_pixmap = NULL;
  685.   static GdkBitmap *qmasknosel_mask   = NULL;
  686.   static GdkPixmap *navbutton_pixmap  = NULL;
  687.   static GdkBitmap *navbutton_mask    = NULL;
  688.  
  689.   GtkWidget *main_vbox;
  690.   GtkWidget *disp_vbox;
  691.   GtkWidget *upper_hbox;
  692.   GtkWidget *lower_hbox;
  693.   GtkWidget *inner_table;
  694.   GtkWidget *status_hbox;
  695.   GtkWidget *arrow;
  696.   GtkWidget *pixmap;
  697.   GtkWidget *label_frame;
  698.   GtkWidget *nav_ebox;
  699.  
  700.   GSList *group = NULL;
  701.  
  702.   gint n_width, n_height;
  703.   gint s_width, s_height;
  704.   gint scalesrc, scaledest;
  705.   gint contextid;
  706.  
  707.   /*  adjust the initial scale -- so that window fits on screen */
  708.   /*  the 75% value is the same as in gdisplay_shrink_wrap. It  */
  709.   /*  probably should be a user-configurable option.            */
  710.   s_width  = gdk_screen_width () * 0.75;
  711.   s_height = gdk_screen_height () * 0.75;
  712.  
  713.   scalesrc  = SCALESRC (gdisp);
  714.   scaledest = SCALEDEST (gdisp);
  715.  
  716.   n_width  = SCALEX (gdisp, width);
  717.   n_height = SCALEX (gdisp, height);
  718.  
  719.   /*  Limit to the size of the screen...  */
  720.   while (n_width > s_width || n_height > s_height)
  721.     {
  722.       if (scaledest > 1)
  723.     scaledest--;
  724.       else
  725.     if (scalesrc < 0xff)
  726.       scalesrc++;
  727.  
  728.       n_width  = width * 
  729.     (scaledest * SCREEN_XRES (gdisp)) / (scalesrc * gdisp->gimage->xresolution);
  730.       n_height = height *
  731.     (scaledest * SCREEN_XRES (gdisp)) / (scalesrc * gdisp->gimage->xresolution);
  732.  
  733.       if (scaledest == 1 && scalesrc == 0xff)
  734.         break;
  735.     }
  736.  
  737.   gdisp->scale = (scaledest << 8) + scalesrc;
  738.  
  739.   /*  the toplevel shell */
  740.   gdisp->shell = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  741.   gtk_widget_ref  (gdisp->shell);
  742.   gtk_window_set_title (GTK_WINDOW (gdisp->shell), title);
  743.   gtk_window_set_wmclass (GTK_WINDOW (gdisp->shell), "image_window", "Gimp");
  744.   gtk_window_set_policy (GTK_WINDOW (gdisp->shell), TRUE, TRUE, TRUE);
  745.   gtk_object_set_user_data (GTK_OBJECT (gdisp->shell), (gpointer) gdisp);
  746.   gtk_widget_set_events (gdisp->shell,
  747.              GDK_POINTER_MOTION_MASK |
  748.              GDK_POINTER_MOTION_HINT_MASK |
  749.              GDK_BUTTON_PRESS_MASK |
  750.              GDK_KEY_PRESS_MASK |
  751.              GDK_KEY_RELEASE_MASK);
  752.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "delete_event",
  753.               GTK_SIGNAL_FUNC (gdisplay_delete),
  754.               gdisp);
  755.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "destroy",
  756.               GTK_SIGNAL_FUNC (gdisplay_destroy),
  757.               gdisp);
  758.  
  759.   /*  active display callback  */
  760.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "button_press_event",
  761.               GTK_SIGNAL_FUNC (gdisplay_shell_events),
  762.               gdisp);
  763.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "key_press_event",
  764.               GTK_SIGNAL_FUNC (gdisplay_shell_events),
  765.               gdisp);
  766.  
  767.   /*  dnd stuff  */
  768.   gtk_drag_dest_set (gdisp->shell,
  769.              GTK_DEST_DEFAULT_ALL,
  770.              display_target_table, display_n_targets,
  771.              GDK_ACTION_COPY);
  772.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "drag_drop",
  773.               GTK_SIGNAL_FUNC (gdisplay_drag_drop),
  774.               gdisp);
  775.   gimp_dnd_color_dest_set (gdisp->shell, gdisplay_drop_color, gdisp);
  776.   gimp_dnd_pattern_dest_set (gdisp->shell, gdisplay_drop_pattern, gdisp);
  777.  
  778.   if (! image_popup_menu)
  779.     menus_get_image_menu (&image_popup_menu, &image_accel_group);
  780.  
  781.   /*  the popup menu  */
  782.   gdisp->popup = image_popup_menu;
  783.  
  784.   /*  The accelerator table for images  */
  785.   gtk_window_add_accel_group (GTK_WINDOW (gdisp->shell), image_accel_group);
  786.  
  787.   /*  connect the "F1" help key  */
  788.   gimp_help_connect_help_accel (gdisp->shell,
  789.                 gimp_standard_help_func,
  790.                 "image/image_window.html");
  791.  
  792.   /*  GtkTable widgets are not able to shrink a row/column correctly if
  793.    *  widgets are attached with GTK_EXPAND even if those widgets have
  794.    *  other rows/columns in their rowspan/colspan where they could
  795.    *  nicely expand without disturbing the row/column which is supposed
  796.    *  to shrink. --Mitch
  797.    *
  798.    *  Changed the packing to use hboxes and vboxes which behave nicer:
  799.    *
  800.    *  main_vbox
  801.    *     |
  802.    *     +-- disp_vbox
  803.    *     |      |
  804.    *     |      +-- upper_hbox
  805.    *     |      |      |
  806.    *     |      |      +-- inner_table
  807.    *     |      |      |      |
  808.    *     |      |      |      +-- origin
  809.    *     |      |      |      +-- hruler
  810.    *     |      |      |      +-- vruler
  811.    *     |      |      |      +-- canvas
  812.    *     |      |      |     
  813.    *     |      |      +-- vscrollbar
  814.    *     |      |    
  815.    *     |      +-- lower_hbox
  816.    *     |             |
  817.    *     |             +-- qmaskoff
  818.    *     |             +-- qmaskon
  819.    *     |             +-- hscrollbar
  820.    *     |             +-- navbutton
  821.    *     |
  822.    *     +-- statusarea
  823.    *            |
  824.    *            +-- cursorlabel
  825.    *            +-- statusbar
  826.    *            +-- progressbar
  827.    *            +-- cancelbutton
  828.    */
  829.  
  830.   /*  first, set up the container hierarchy  *********************************/
  831.  
  832.   /*  the vbox containing all widgets  */
  833.   main_vbox = gtk_vbox_new (FALSE, 2);
  834.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
  835.   gtk_container_add (GTK_CONTAINER (gdisp->shell), main_vbox);
  836.  
  837.   /*  another vbox for everything except the statusbar  */
  838.   disp_vbox = gtk_vbox_new (FALSE, 1);
  839.   gtk_box_pack_start (GTK_BOX (main_vbox), disp_vbox, TRUE, TRUE, 0);
  840.   gtk_widget_show (disp_vbox);
  841.  
  842.   /*  a hbox for the inner_table and the vertical scrollbar  */
  843.   upper_hbox = gtk_hbox_new (FALSE, 1);
  844.   gtk_box_pack_start (GTK_BOX (disp_vbox), upper_hbox, TRUE, TRUE, 0);
  845.   gtk_widget_show (upper_hbox);
  846.  
  847.   /*  the table containing origin, rulers and the canvas  */
  848.   inner_table = gtk_table_new (2, 2, FALSE);
  849.   gtk_table_set_col_spacing (GTK_TABLE (inner_table), 0, 1);
  850.   gtk_table_set_row_spacing (GTK_TABLE (inner_table), 0, 1);
  851.   gtk_box_pack_start (GTK_BOX (upper_hbox), inner_table, TRUE, TRUE, 0);
  852.   gtk_widget_show (inner_table);
  853.  
  854.   /*  the hbox containing qmask buttons, vertical scrollbar and nav button  */
  855.   lower_hbox = gtk_hbox_new (FALSE, 1);
  856.   gtk_box_pack_start (GTK_BOX (disp_vbox), lower_hbox, FALSE, FALSE, 0);
  857.   gtk_widget_show (lower_hbox);
  858.  
  859.   /*  eventbox and hbox for status area  */
  860.   gdisp->statusarea = gtk_event_box_new ();
  861.   gtk_box_pack_start (GTK_BOX (main_vbox), gdisp->statusarea, FALSE, FALSE, 0);
  862.  
  863.   gimp_help_set_help_data (gdisp->statusarea, NULL, "#status_area");
  864.  
  865.   status_hbox = gtk_hbox_new (FALSE, 2);
  866.   gtk_container_add (GTK_CONTAINER (gdisp->statusarea), status_hbox);
  867.   gtk_widget_show (status_hbox);
  868.  
  869.   gtk_container_set_resize_mode (GTK_CONTAINER (status_hbox),
  870.                  GTK_RESIZE_QUEUE);
  871.  
  872.   /*  create the scrollbars  *************************************************/
  873.  
  874.   /*  the horizontal scrollbar  */
  875.   gdisp->hsbdata =
  876.     GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, width, 1, 1, width));
  877.   gdisp->hsb = gtk_hscrollbar_new (gdisp->hsbdata);
  878.   GTK_WIDGET_UNSET_FLAGS (gdisp->hsb, GTK_CAN_FOCUS);
  879.  
  880.   /*  the vertical scrollbar  */
  881.   gdisp->vsbdata =
  882.     GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, height, 1, 1, height));
  883.   gdisp->vsb = gtk_vscrollbar_new (gdisp->vsbdata);
  884.   GTK_WIDGET_UNSET_FLAGS (gdisp->vsb, GTK_CAN_FOCUS);
  885.  
  886.   /*  create the contents of the inner_table  ********************************/
  887.  
  888.   /*  the menu popup button  */
  889.   gdisp->origin = gtk_button_new ();
  890.   GTK_WIDGET_UNSET_FLAGS (gdisp->origin, GTK_CAN_FOCUS);
  891.   gtk_widget_set_events (GTK_WIDGET (gdisp->origin),
  892.              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  893.   gtk_signal_connect (GTK_OBJECT (gdisp->origin), "button_press_event",
  894.               GTK_SIGNAL_FUNC (gdisplay_origin_button_press),
  895.               gdisp);
  896.  
  897.   gimp_help_set_help_data (gdisp->origin, NULL, "#origin_button");
  898.  
  899.   arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
  900.   gtk_container_set_border_width (GTK_CONTAINER (gdisp->origin), 0);
  901.   gtk_container_add (GTK_CONTAINER (gdisp->origin), arrow);
  902.   gtk_widget_show (arrow);
  903.  
  904.   /*  the horizontal ruler  */
  905.   gdisp->hrule = gtk_hruler_new ();
  906.   gtk_widget_set_events (GTK_WIDGET (gdisp->hrule),
  907.              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  908.   gtk_signal_connect_object (GTK_OBJECT (gdisp->shell), "motion_notify_event",
  909.                  GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (gdisp->hrule)->klass)->motion_notify_event),
  910.                  GTK_OBJECT (gdisp->hrule));
  911.   gtk_signal_connect (GTK_OBJECT (gdisp->hrule), "button_press_event",
  912.               GTK_SIGNAL_FUNC (gdisplay_hruler_button_press),
  913.               gdisp);
  914.  
  915.   gimp_help_set_help_data (gdisp->hrule, NULL, "#ruler");
  916.  
  917.   /*  the vertical ruler  */
  918.   gdisp->vrule = gtk_vruler_new ();
  919.   gtk_widget_set_events (GTK_WIDGET (gdisp->vrule),
  920.              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  921.   gtk_signal_connect_object (GTK_OBJECT (gdisp->shell), "motion_notify_event",
  922.                  GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (gdisp->vrule)->klass)->motion_notify_event),
  923.                  GTK_OBJECT (gdisp->vrule));
  924.   gtk_signal_connect (GTK_OBJECT (gdisp->vrule), "button_press_event",
  925.               GTK_SIGNAL_FUNC (gdisplay_vruler_button_press),
  926.               gdisp);
  927.  
  928.   gimp_help_set_help_data (gdisp->vrule, NULL, "#ruler");
  929.  
  930.   /*  the canvas  */
  931.   gdisp->canvas = gtk_drawing_area_new ();
  932.   gtk_drawing_area_size (GTK_DRAWING_AREA (gdisp->canvas), n_width, n_height);
  933.   gtk_widget_set_events (gdisp->canvas, CANVAS_EVENT_MASK);
  934.   gtk_widget_set_extension_events (gdisp->canvas, GDK_EXTENSION_EVENTS_ALL);
  935.   GTK_WIDGET_SET_FLAGS (gdisp->canvas, GTK_CAN_FOCUS);
  936.   gtk_object_set_user_data (GTK_OBJECT (gdisp->canvas), (gpointer) gdisp);
  937.  
  938.   /*  set the active display before doing any other canvas event processing  */
  939.   gtk_signal_connect (GTK_OBJECT (gdisp->canvas), "event",
  940.               GTK_SIGNAL_FUNC (gdisplay_shell_events),
  941.               gdisp);
  942.   gtk_signal_connect (GTK_OBJECT (gdisp->canvas), "event",
  943.               GTK_SIGNAL_FUNC (gdisplay_canvas_events),
  944.               gdisp);
  945.  
  946.   /*  create the contents of the lower_hbox  *********************************/
  947.  
  948.   /*  the qmask buttons  */
  949.   gdisp->qmaskoff = gtk_radio_button_new (group);
  950.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskoff));
  951.   gtk_widget_set_usize (GTK_WIDGET (gdisp->qmaskoff), 15, 15);
  952.   gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), FALSE);
  953.   GTK_WIDGET_UNSET_FLAGS (gdisp->qmaskoff, GTK_CAN_FOCUS);
  954.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "toggled",
  955.               GTK_SIGNAL_FUNC (qmask_deactivate),
  956.               gdisp);
  957.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "button_press_event",
  958.               GTK_SIGNAL_FUNC (qmask_click_handler),
  959.               gdisp);
  960.  
  961.   gimp_help_set_help_data (gdisp->qmaskoff, NULL, "#qmask_off_button");
  962.  
  963.   gdisp->qmaskon = gtk_radio_button_new (group);
  964.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskon));
  965.   gtk_widget_set_usize (GTK_WIDGET (gdisp->qmaskon), 15, 15);
  966.   gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskon), FALSE);
  967.   GTK_WIDGET_UNSET_FLAGS (gdisp->qmaskon, GTK_CAN_FOCUS);
  968.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "toggled",
  969.               GTK_SIGNAL_FUNC (qmask_activate),
  970.               gdisp);
  971.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "button_press_event",
  972.               GTK_SIGNAL_FUNC (qmask_click_handler),
  973.               gdisp);
  974.  
  975.   gimp_help_set_help_data (gdisp->qmaskon, NULL, "#qmask_on_button");
  976.  
  977.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), TRUE);
  978.  
  979.   /*  the navigation window button  */
  980.   nav_ebox = gtk_event_box_new ();
  981.   gtk_signal_connect (GTK_OBJECT (nav_ebox), "button_press_event",
  982.               GTK_SIGNAL_FUNC (nav_popup_click_handler),
  983.               gdisp);
  984.  
  985.   gimp_help_set_help_data (nav_ebox, NULL, "#nav_window_button");
  986.  
  987.   /*  create the pixmaps  ****************************************************/
  988.   if (!qmasksel_pixmap)
  989.     {
  990.       GtkStyle *style;
  991.  
  992.       gtk_widget_realize (gdisp->shell);
  993.       style = gtk_widget_get_style (gdisp->shell);
  994.  
  995.       qmasksel_pixmap =
  996.     gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
  997.                       &qmasksel_mask,
  998.                       &style->bg[GTK_STATE_NORMAL],
  999.                       qmasksel_xpm);   
  1000.       qmasknosel_pixmap =
  1001.     gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
  1002.                       &qmasknosel_mask,
  1003.                       &style->bg[GTK_STATE_NORMAL],
  1004.                       qmasknosel_xpm);   
  1005.       navbutton_pixmap =
  1006.     gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
  1007.                       &navbutton_mask,
  1008.                       &style->bg[GTK_STATE_NORMAL],
  1009.                       navbutton_xpm);   
  1010.     }
  1011.  
  1012.   /*  create the GtkPixmaps  */
  1013.   pixmap = gtk_pixmap_new (qmasksel_pixmap, qmasksel_mask);
  1014.   gtk_container_add (GTK_CONTAINER (gdisp->qmaskon), pixmap);
  1015.   gtk_widget_show (pixmap);
  1016.  
  1017.   pixmap = gtk_pixmap_new (qmasknosel_pixmap, qmasknosel_mask);
  1018.   gtk_container_add (GTK_CONTAINER (gdisp->qmaskoff), pixmap);
  1019.   gtk_widget_show (pixmap);
  1020.  
  1021.   pixmap = gtk_pixmap_new (navbutton_pixmap, navbutton_mask);
  1022.   gtk_container_add (GTK_CONTAINER (nav_ebox), pixmap); 
  1023.   gtk_widget_show (pixmap);
  1024.  
  1025.   /*  create the contents of the status area *********************************/
  1026.  
  1027.   /*  the cursor label  */
  1028.   label_frame = gtk_frame_new (NULL);
  1029.   gtk_frame_set_shadow_type (GTK_FRAME (label_frame), GTK_SHADOW_IN);
  1030.  
  1031.   gdisp->cursor_label = gtk_label_new (" ");
  1032.   gtk_container_add (GTK_CONTAINER (label_frame), gdisp->cursor_label);
  1033.   gtk_widget_show (gdisp->cursor_label);
  1034.  
  1035.   /*  the statusbar  */
  1036.   gdisp->statusbar = gtk_statusbar_new ();
  1037.   gtk_widget_set_usize (gdisp->statusbar, 1, -1);
  1038.   gtk_container_set_resize_mode (GTK_CONTAINER (gdisp->statusbar),
  1039.                  GTK_RESIZE_QUEUE);
  1040.   contextid = gtk_statusbar_get_context_id (GTK_STATUSBAR (gdisp->statusbar),
  1041.                         "title");
  1042.   gtk_statusbar_push (GTK_STATUSBAR (gdisp->statusbar),
  1043.               contextid,
  1044.               title);
  1045.  
  1046.   /*  the progress bar  */
  1047.   gdisp->progressbar = gtk_progress_bar_new ();
  1048.   gtk_widget_set_usize (gdisp->progressbar, 80, -1);
  1049.  
  1050.   /*  the cancel button  */
  1051.   gdisp->cancelbutton = gtk_button_new_with_label (_("Cancel"));
  1052.   gtk_widget_set_sensitive (gdisp->cancelbutton, FALSE);
  1053.  
  1054.   /*  pack all the widgets  **************************************************/
  1055.  
  1056.   /*  fill the upper_hbox  */
  1057.   gtk_box_pack_start (GTK_BOX (upper_hbox), gdisp->vsb, FALSE, FALSE, 0);
  1058.  
  1059.   /*  fill the inner_table  */
  1060.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->origin, 0, 1, 0, 1,
  1061.             GTK_FILL, GTK_FILL, 0, 0);
  1062.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->hrule, 1, 2, 0, 1,
  1063.             GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
  1064.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->vrule, 0, 1, 1, 2,
  1065.             GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
  1066.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->canvas, 1, 2, 1, 2,
  1067.             GTK_EXPAND | GTK_SHRINK | GTK_FILL,
  1068.             GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
  1069.  
  1070.   /*  fill the lower_hbox  */
  1071.   gtk_box_pack_start (GTK_BOX (lower_hbox), gdisp->qmaskoff, FALSE, FALSE, 0);
  1072.   gtk_box_pack_start (GTK_BOX (lower_hbox), gdisp->qmaskon, FALSE, FALSE, 0);
  1073.   gtk_box_pack_start (GTK_BOX (lower_hbox), gdisp->hsb, TRUE, TRUE, 0);
  1074.   gtk_box_pack_start (GTK_BOX (lower_hbox), nav_ebox, FALSE, FALSE, 0);
  1075.  
  1076.   /*  fill the status area  */
  1077.   gtk_box_pack_start (GTK_BOX (status_hbox), label_frame, FALSE, FALSE, 0);
  1078.   gtk_box_pack_start (GTK_BOX (status_hbox), gdisp->statusbar, TRUE, TRUE, 0);
  1079.   gtk_box_pack_start (GTK_BOX (status_hbox), gdisp->progressbar, FALSE, FALSE, 0);
  1080.   gtk_box_pack_start (GTK_BOX (status_hbox), gdisp->cancelbutton, FALSE, FALSE, 0);
  1081.  
  1082.   /*  show everything  *******************************************************/
  1083.  
  1084.   if (show_rulers)
  1085.     {
  1086.       gtk_widget_show (gdisp->origin);
  1087.       gtk_widget_show (gdisp->hrule);
  1088.       gtk_widget_show (gdisp->vrule);
  1089.     }
  1090.   gtk_widget_show (gdisp->canvas);
  1091.  
  1092.   gtk_widget_show (gdisp->vsb);
  1093.   gtk_widget_show (gdisp->hsb);
  1094.  
  1095.   gtk_widget_show (gdisp->qmaskoff);
  1096.   gtk_widget_show (gdisp->qmaskon);
  1097.   gtk_widget_show (nav_ebox);
  1098.  
  1099.   gtk_widget_show (label_frame);
  1100.   gtk_widget_show (gdisp->statusbar);
  1101.   gtk_widget_show (gdisp->progressbar);
  1102.   gtk_widget_show (gdisp->cancelbutton);
  1103.   if (show_statusbar)
  1104.     {
  1105.       gtk_widget_show (gdisp->statusarea);
  1106.     }
  1107.  
  1108.   gtk_widget_realize (gdisp->canvas);
  1109.   gdk_window_set_back_pixmap (gdisp->canvas->window, NULL, FALSE);
  1110.  
  1111.   /*  we need to realize the cursor_label widget here, so the size gets
  1112.    *  computed correctly
  1113.    */
  1114.   gtk_widget_realize (gdisp->cursor_label);
  1115.   gdisplay_resize_cursor_label (gdisp);
  1116.  
  1117.   gtk_widget_show (main_vbox);
  1118.   gtk_widget_show (gdisp->shell);
  1119.  
  1120.   /*  set the focus to the canvas area  */
  1121.   gtk_widget_grab_focus (gdisp->canvas);
  1122. }
  1123.  
  1124. /* DnD functions */ 
  1125. static void
  1126. toolbox_set_drag_dest (GtkWidget *object)
  1127. {
  1128.   gtk_drag_dest_set (object,
  1129.              GTK_DEST_DEFAULT_ALL,
  1130.              toolbox_target_table, toolbox_n_targets,
  1131.              GDK_ACTION_COPY);
  1132.  
  1133.   gimp_dnd_file_dest_set (object);
  1134.  
  1135.   gtk_signal_connect (GTK_OBJECT (object), "drag_drop",
  1136.               GTK_SIGNAL_FUNC (toolbox_drag_drop),
  1137.               NULL);
  1138.  
  1139.   gimp_dnd_tool_dest_set (object, toolbox_drop_tool, NULL);
  1140. }
  1141.  
  1142. static gboolean
  1143. toolbox_drag_drop (GtkWidget      *widget,
  1144.            GdkDragContext *context,
  1145.            gint            x,
  1146.            gint            y,
  1147.            guint           time)
  1148. {
  1149.   GtkWidget *src_widget;
  1150.   gboolean return_val = FALSE;
  1151.  
  1152.   if ((src_widget = gtk_drag_get_source_widget (context)))
  1153.     {
  1154.       GimpDrawable *drawable       = NULL;
  1155.       Layer        *layer          = NULL;
  1156.       Channel      *channel        = NULL;
  1157.       LayerMask    *layer_mask     = NULL;
  1158.       GImage       *component      = NULL;
  1159.       ChannelType   component_type = -1;
  1160.  
  1161.       layer = (Layer *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1162.                          "gimp_layer");
  1163.       channel = (Channel *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1164.                          "gimp_channel");
  1165.       layer_mask = (LayerMask *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1166.                               "gimp_layer_mask");
  1167.       component = (GImage *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1168.                           "gimp_component");
  1169.  
  1170.       if (layer)
  1171.     {
  1172.       drawable = GIMP_DRAWABLE (layer);
  1173.     }
  1174.       else if (channel)
  1175.     {
  1176.       drawable = GIMP_DRAWABLE (channel);
  1177.     }
  1178.       else if (layer_mask)
  1179.     {
  1180.       drawable = GIMP_DRAWABLE (layer_mask);
  1181.     }
  1182.       else if (component)
  1183.     {
  1184.       component_type =
  1185.         (ChannelType) gtk_object_get_data (GTK_OBJECT (src_widget),
  1186.                            "gimp_component_type");
  1187.     }
  1188.  
  1189.       if (drawable)
  1190.     {
  1191.           GImage *gimage;
  1192.       GImage *new_gimage;
  1193.       Layer  *new_layer;
  1194.           gint    width, height;
  1195.       gint    off_x, off_y;
  1196.       gint    bytes;
  1197.  
  1198.       GimpImageBaseType type;
  1199.  
  1200.       gimage = gimp_drawable_gimage (drawable);
  1201.           width  = gimp_drawable_width  (drawable);
  1202.           height = gimp_drawable_height (drawable);
  1203.       bytes  = gimp_drawable_bytes  (drawable);
  1204.  
  1205.       switch (gimp_drawable_type (drawable))
  1206.         {
  1207.         case RGB_GIMAGE: case RGBA_GIMAGE:
  1208.           type = RGB; break;
  1209.         case GRAY_GIMAGE: case GRAYA_GIMAGE:
  1210.           type = GRAY; break;
  1211.         case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
  1212.           type = INDEXED; break;
  1213.         default:
  1214.           type = RGB; break;
  1215.         }
  1216.  
  1217.       new_gimage = gimage_new (width, height, type);
  1218.       gimage_disable_undo (new_gimage);
  1219.  
  1220.       if (type == INDEXED) /* copy the colormap */
  1221.         {
  1222.           new_gimage->num_cols = gimage->num_cols;
  1223.           memcpy (new_gimage->cmap, gimage->cmap, COLORMAP_SIZE);
  1224.         }
  1225.  
  1226.       gimage_set_resolution (new_gimage, gimage->xresolution, gimage->yresolution);
  1227.       gimage_set_unit (new_gimage, gimage->unit);
  1228.  
  1229.       if (layer)
  1230.         {
  1231.           new_layer = layer_copy (layer, FALSE);
  1232.         }
  1233.       else
  1234.         {
  1235.           /*  a non-layer drawable can't have an alpha channel,
  1236.            *  so add one
  1237.            */
  1238.           PixelRegion  srcPR, destPR;
  1239.           TileManager *tiles;
  1240.  
  1241.           tiles = tile_manager_new (width, height, bytes + 1);
  1242.  
  1243.           pixel_region_init (&srcPR, gimp_drawable_data (drawable),
  1244.                  0, 0, width, height, FALSE);
  1245.           pixel_region_init (&destPR, tiles,
  1246.                  0, 0, width, height, TRUE);
  1247.  
  1248.           add_alpha_region (&srcPR, &destPR);
  1249.  
  1250.           new_layer = layer_new_from_tiles (new_gimage, 
  1251.                                                 gimp_image_base_type_with_alpha(new_gimage), 
  1252.                                                 tiles,
  1253.                         "", OPAQUE_OPACITY, NORMAL_MODE);
  1254.  
  1255.           tile_manager_destroy (tiles);
  1256.         }
  1257.  
  1258.       gimp_drawable_set_gimage (GIMP_DRAWABLE (new_layer), new_gimage);
  1259.  
  1260.       layer_set_name (GIMP_LAYER (new_layer),
  1261.               gimp_drawable_get_name (drawable));
  1262.  
  1263.       if (layer)
  1264.         {
  1265.           LayerMask *mask;
  1266.           LayerMask *new_mask;
  1267.  
  1268.           mask     = layer_get_mask (layer);
  1269.           new_mask = layer_get_mask (new_layer);
  1270.  
  1271.           if (new_mask)
  1272.         {
  1273.           gimp_drawable_set_name (GIMP_DRAWABLE (new_mask),
  1274.                       gimp_drawable_get_name (GIMP_DRAWABLE (mask)));
  1275.         }
  1276.         }
  1277.  
  1278.       gimp_drawable_offsets (GIMP_DRAWABLE (new_layer), &off_x, &off_y);
  1279.       layer_translate (new_layer, -off_x, -off_y);
  1280.  
  1281.       gimage_add_layer (new_gimage, new_layer, 0);
  1282.  
  1283.       gimp_context_set_display (gimp_context_get_user (),
  1284.                     gdisplay_new (new_gimage, 0x0101));
  1285.  
  1286.       gimage_enable_undo (new_gimage);
  1287.  
  1288.       return_val = TRUE;
  1289.     }
  1290.     }
  1291.  
  1292.   gtk_drag_finish (context, return_val, FALSE, time);
  1293.  
  1294.   return return_val;
  1295. }
  1296.  
  1297. static ToolType
  1298. toolbox_drag_tool (GtkWidget *widget,
  1299.            gpointer   data)
  1300. {
  1301.   return (ToolType) data;
  1302. }
  1303.  
  1304. static void
  1305. toolbox_drop_tool (GtkWidget *widget,
  1306.            ToolType   tool,
  1307.            gpointer   data)
  1308. {
  1309.   gimp_context_set_tool (gimp_context_get_user (), tool);
  1310. }
  1311.